import json
import traceback
from django.http import JsonResponse
from django.views.generic import View
from ..serializers.unitSerializer import *
from django.db.models import Q
from django.core.paginator import Paginator
from utils.encryptionAndDecryptionUtil import get_user_from_useraccount, get_useraccount_from_request
from ..config.message_config import *
from ..utils.common_util.basic_util import get_order_list_combined
from ..utils.related_util.used_util import is_unit_used
from basic_component_related_management.models import ComponentConstPropertyValue
from ..models import QuantityUnitMap
from utils.responseContentUtil import *


class UnitView(View):
    def get(self, request):
        res = {"code": 400, "message": "", "data": None}
        try:
            data = request.GET
            query_list_serializer = UnitListQuerySerializer(data=data)
            data_valid = query_list_serializer.is_valid()
            if not data_valid:
                return make_get_error_response(message=query_list_serializer.errors)
            data = query_list_serializer.validated_data
            query = Q()
            query &= Q(valid_flag=True)
            if "unit_name" in data:
                query &= (Q(unit_name__icontains=data["unit_name"])|Q(unit_name_en__icontains=data["unit_name"]))
            if "sei_id" in data:
                query &= Q(sei_id__icontains=data["sei_id"])
            if "unit_symbol" in data:
                query &= Q(unit_symbol__icontains=data["unit_symbol"])
            if "dimension" in data:
                query &= Q(dimension=data["dimension"])
            order_list_combined = get_order_list_combined(data)
            if len(order_list_combined) == 0:
                units = Unit.objects.filter(query).order_by("-create_date")
            else:
                units = Unit.objects.filter(
                    query).order_by(*order_list_combined)
            page_size = data["page_size"]
            current_page = data["current_page"]
            total_count = units.count()
            paginator = Paginator(units, page_size)
            if current_page > paginator.num_pages:
                current_page = paginator.num_pages
            page_obj = paginator.get_page(current_page)
            res_data = {}
            res_data["current_page"] = current_page
            res_data["page_size"] = page_size
            res_data["total_count"] = total_count
            unit_list_serializer = UnitListSerializer(page_obj, many=True)
            res_data["objects"] = unit_list_serializer.data
            return make_get_success_response(data=res_data)
        except Exception as e:
            traceback.print_exc()
            return make_server_error_response(str(e))

    def post(self,request):
        res = {"code": 400, "message": "", "data": None}
        try:
            user_name = get_useraccount_from_request(request)
            user = get_user_from_useraccount(user_name)
            data = json.loads(request.body)
            create_serializer = UnitCreateSerializer(data=data)
            data_valid = create_serializer.is_valid()
            if not data_valid:
                res["code"] = 400
                res_message = "参数错误:\n"
                if "unit_name" in create_serializer.errors:
                    res_message += "单位中文名称已存在;\n"
                if "unit_name_en" in create_serializer.errors:
                    res_message += "单位英文名称已存在;\n"
                if "sei_id" in create_serializer.errors:
                    res_message += "编码已存在;\n"
                if "conversion_factor" in create_serializer.errors:
                    res_message += "换算乘数不能为0;\n"
                return make_create_error_response(message=res_message)
            data = create_serializer.validated_data
            data["dimension"] = Dimension.objects.filter(uuid = data["dimension"],valid_flag = True).first()
            if "prefix" in data:
                data["prefix"] = UnitPrefix.objects.filter(uuid = data["prefix"],valid_flag = True).first()
            if "root_unit" in data:
                data["root_unit"] = Unit.objects.filter(uuid = data["root_unit"],valid_flag = True).first()
            unit = Unit.objects.create(
                **data, create_person=user, modify_person=user)
            return make_create_success_response()
        except Exception as e:
            traceback.print_exc()
            return make_server_error_response(str(e))

class UnitInfoView(View):
    def get(self,request,uuid):
        res = {"code": 400, "message": "", "data": None}
        try:
            get_params = request.GET
            info_get_type = get_params.get("type", "")
            unit = Unit.objects.filter(uuid=uuid,valid_flag=True).first()
            if unit == None:
                return make_get_error_response(message="该条目不存在")
            if info_get_type == "modify":
                unit_serializer = UnitModifyInfoSerializer(unit)
                res_data = unit_serializer.data
                uesd_flag,used_message = is_unit_used(unit)
                res_data["unit_conversion_flag"] = uesd_flag
                return make_get_success_response(data=res_data)
            else:
                unit_serializer = UnitInfoSerializer(unit)
                return make_get_success_response(data=unit_serializer.data)
        except Exception as e:
            traceback.print_exc()
            return make_server_error_response(str(e))
    
    def put(self,request,uuid):
        res = {"code": 400, "message": "", "data": None}
        try:
            user_name = get_useraccount_from_request(request)
            user = get_user_from_useraccount(user_name)
            data = json.loads(request.body)
            unit = Unit.objects.filter(uuid=uuid,valid_flag=True).first()
            if unit == None:
                return make_update_error_response(message="该条目不存在")
            modify_serializer = UnitModifyInfoInSerializer(unit,data=data)
            data_valid = modify_serializer.is_valid()
            if not data_valid:
                res["code"] = 400
                res_message = "参数错误:\n"
                if "unit_name" in modify_serializer.errors:
                    res_message += "单位中文名称已存在;\n"
                if "unit_name_en" in modify_serializer.errors:
                    res_message += "单位英文名称已存在;\n"
                if "sei_id" in modify_serializer.errors:
                    res_message += "编码已存在;\n"
                if "conversion_factor" in modify_serializer.errors:
                    res_message += "换算乘数不能为0;\n"
                return make_update_error_response(message=res_message)
            data = modify_serializer.validated_data
            data["dimension"] = Dimension.objects.filter(uuid = data["dimension"],valid_flag = True).first()
            if "prefix" in data:
                data["prefix"] = UnitPrefix.objects.filter(uuid = data["prefix"],valid_flag = True).first()
            if "root_unit" in data:
                data["root_unit"] = Unit.objects.filter(uuid = data["root_unit"],valid_flag = True).first()
            for field in data:
                setattr(unit,field,data[field])
            unit.modify_person = user
            unit.save()
            return make_update_success_response()
        except Exception as e:
            traceback.print_exc()
            return make_server_error_response(str(e))

    def delete(self,request,uuid):
        res = {"code": 400, "message": "", "data": None}
        try:
            user_name = get_useraccount_from_request(request)
            user = get_user_from_useraccount(user_name)
            unit = Unit.objects.filter(uuid=uuid,valid_flag=True).first()
            if unit == None:
                return make_delete_error_response(message="该条目不存在")            
            uesd_flag,used_message = is_unit_used(unit)
            if uesd_flag:
                return make_delete_error_response(message=used_message)
            # 判断量是否引用该单位
            quantity_unit_map_first = QuantityUnitMap.objects.filter(
                unit=unit, quantity__valid_flag=True).first()
            if quantity_unit_map_first:
                return make_delete_error_response(message="该单位被量引用")

            # 判断推荐物性是否引用该单位
            const_property_unit = ComponentConstPropertyValue.objects.filter(
                component__valid_flag=True,property__valid_flag=True,property_unit=unit
            ).first()
            if const_property_unit:
                return make_delete_error_response(message="该单位被推荐物性引用")

            unit.valid_flag = False
            unit.modify_person = user
            unit.save()
            return make_delete_success_response()
        except Exception as e:
            traceback.print_exc()
            return make_server_error_response(str(e))
    